using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using System.Configuration;

namespace Callista.TFSBuildAlert
{
    public enum TFSEventType
    {
        AclChangedEvent,
        BranchMovedEvent,
        BuildCompletionEvent,
        BuildStatusChangeEvent,
        CheckinEvent,
        CommonStructureChangedEvent,
        DataChangedEvent,
        IdentityCreatedEvent,
        IdentityDeletedEvent,
        MembershipChangedEvent,
        NodeCreatedEvent,
        NodePropertiesChangedEvent,
        NodeRenamedEvent,
        NodesDeletedEvent,
        ProjectCreatedEvent,
        ProjectDeletedEvent,
        WorkItemChangedEvent
    }

    public class SubscriptionService
    {
        private TeamFoundationServer _tfs;
        private IEventService _eventService;
        private List<Subscription> _subscriptions = null;
        private string _userId = null;
        private string _tagPrefix;

        public SubscriptionService(TeamFoundationServer tfs, string tagPrefix)
        {
            _tfs = tfs;
            _eventService = (IEventService)tfs.GetService(typeof(IEventService));
            _userId = _tfs.AuthenticatedUserName;
            _tagPrefix = tagPrefix;
            _subscriptions = new List<Subscription>(_eventService.EventSubscriptions(_userId));
        }

        private DeliveryPreference GetDeliveryPreference(string address)
        {
            DeliveryPreference dp = new DeliveryPreference();
            dp.Address = address;
            dp.Schedule = DeliverySchedule.Immediate;
            dp.Type = DeliveryType.Soap;
            return dp;
        }

        public void DeleteSubscription(TFSEventType eventType)
        {
            foreach (Subscription s in _subscriptions)
            {
                if (s.EventType == eventType.ToString() && s.Tag.StartsWith(_tagPrefix))
                {
                    Unsubscribe(s.ID);
                    _subscriptions = new List<Subscription>(_eventService.EventSubscriptions(_userId));
                    return;
                }
            }
        }

        public void DeleteSubscriptions()
        {
            foreach (Subscription s in _subscriptions)
            {
                if (s.Tag.StartsWith(_tagPrefix))
                {
                    Unsubscribe(s.ID);
                }
            }
        }

        public void AddSubscription(TFSEventType eventType, string address)
        {
            string tag = string.Format("{0}:{1}", _tagPrefix, eventType.ToString());
            foreach (Subscription s in _subscriptions)
            {
                if (s.Tag == tag)
                {
                    if (s.DeliveryPreference.Address == address)
                        return;
                    else
                        Unsubscribe(s.ID);
                }
            }
            Subscribe(eventType, tag, _userId, address);
            _subscriptions = new List<Subscription>(_eventService.EventSubscriptions(_userId));
        }

        private void Subscribe(TFSEventType eventType, string tag, string userId, string address)
        {
            int id = _eventService.SubscribeEvent(userId, eventType.ToString(), "", GetDeliveryPreference(address), tag);
        }

        private void Unsubscribe(int subscriptionId)
        {
            _eventService.UnsubscribeEvent(subscriptionId);
        }

        internal TFSEventType GetEventType(int id)
        {
            foreach (Subscription s in _subscriptions)
            {
                if (s.ID == id)
                {
                    return (TFSEventType)Enum.Parse(typeof(TFSEventType), s.EventType);
                }
            }
            throw new ArgumentException("EventType not found in enumerator.");
        }
    }
}
